package com.qf.main.pharmacy.service.impl;

import cn.hutool.core.lang.Snowflake;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.qf.common.base.ex.ServiceException;
import com.qf.common.base.result.ResultStatus;
import com.qf.common.db.utils.CommonBeanutils;
import com.qf.main.pharmacy.common.qo.OrderMallQo;
import com.qf.main.pharmacy.common.qo.OrderQo;
import com.qf.main.pharmacy.common.vo.OrderVo;
import com.qf.main.pharmacy.entity.Order;
import com.qf.main.pharmacy.entity.OrderMall;
import com.qf.main.pharmacy.entity.PharmacyInventory;
import com.qf.main.pharmacy.mapper.OrderMallMapper;
import com.qf.main.pharmacy.mapper.OrderMapper;
import com.qf.main.pharmacy.mapper.PharmacyInventoryMapper;
import com.qf.main.pharmacy.service.AddressService;
import com.qf.main.pharmacy.service.OrderMallService;
import com.qf.main.pharmacy.service.OrderService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author chengqiang
 * @Create 2024-02-19-9:05
 * @Description:
 */
@Service
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private OrderMallMapper orderMallMapper;
    @Resource
    private AddressService addressService;
    @Resource
    private OrderMallService orderMallService;
    @Resource
    private PharmacyInventoryMapper pharmacyInventoryMapper;



    @Transactional
    @Override
    public long saveOrder(OrderQo orderQo){
        Order order = CommonBeanutils.convertTo(orderQo, Order::new);
        // 添加订单id 雪花算法
        Snowflake snowflake = new Snowflake();
        Long id = snowflake.nextId();
        order.setOrderNo(id);
        orderMapper.insert(order);
        List<OrderMall> orderMalls = CommonBeanutils.convertListTo(orderQo.getOrderMallQoList(), OrderMall::new);
        orderMalls.stream().forEach(orderMall -> {
            orderMall.setOrderNo(id);
            QueryWrapper<PharmacyInventory> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq(PharmacyInventory.COL_PHARMACY_ID,orderMall.getOrderMallId());
            if(pharmacyInventoryMapper.selectOne(queryWrapper).getPharmacyInventory()<orderMall.getOrderMallNumber()){
                throw  new ServiceException(ResultStatus.USER_USERNAME_PASSWORD);
            }
            pharmacyInventoryMapper.increaseClaimQuantity(orderMall.getOrderMallId(),orderMall.getOrderMallNumber());
            orderMallMapper.insert(orderMall);
        });


        return id;
    }
    @Override
    public List<OrderVo> orderByIdList(int pageNum ,int pageSize,int userId){

        QueryWrapper<Order> qw = new QueryWrapper<>();
        qw.eq(Order.COL_USER_ID,userId).orderByDesc("create_date");
        PageInfo<Order> PageInfo = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(
                () -> orderMapper.selectList(qw));

        List<OrderVo> collect = PageInfo.getList().stream().map(order -> {
            OrderVo orderVo = CommonBeanutils.convertTo(order, OrderVo::new);
            orderVo.setOrderAddress(addressService.getAddressById(order.getOrderAddress()));
            orderVo.setOrderMall(orderMallService.listOrderMall(order.getOrderNo()));
            return orderVo;
        }).collect(Collectors.toList());
        // PageInfo.setList(collect);
        // new PageInfo<>()
        return collect;
    }
    @Override
    public List<OrderVo> orderList(int pageNum ,int pageSize,String orderNo,Integer status){

        QueryWrapper<Order> qw = new QueryWrapper<>();
        qw.eq(!StringUtils.isEmpty(orderNo),Order.COL_ORDER_NO,orderNo);
        qw.eq(!ObjectUtils.isEmpty(status),Order.COL_ORDER_STATUS,status);
        qw.orderByDesc("create_date");

        PageInfo<Order> PageInfo = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(
                () -> orderMapper.selectList(qw));

        List<OrderVo> collect = PageInfo.getList().stream().map(order -> {
            OrderVo orderVo = CommonBeanutils.convertTo(order, OrderVo::new);
            orderVo.setOrderAddress(addressService.getAddressById(order.getOrderAddress()));
            orderVo.setOrderMall(orderMallService.listOrderMall(order.getOrderNo()));
            return orderVo;
        }).collect(Collectors.toList());
        // PageInfo.setList(collect);
        // new PageInfo<>()
        return collect;
    }

    @Override
    public Integer modifyOrder(OrderQo orderQo) {
        Order order = CommonBeanutils.convertTo(orderQo, Order::new);
        QueryWrapper<Order> qw = new QueryWrapper<>();
        qw.eq(Order.COL_ORDER_NO,orderQo.getOrderNo());
        return orderMapper.update(order,qw);
    }



    @Override
    public Integer removeOrder(int id) {
        QueryWrapper<Order> qw = new QueryWrapper<>();
        qw.eq(Order.COL_ORDER_ID,id);
        return orderMapper.delete(qw);
    }

    @Override
    public Integer recoverOrder(int id) {
        QueryWrapper<Order> qw = new QueryWrapper<>();
        qw.eq(Order.COL_ORDER_ID,id);
        Order order = new Order();
        order.setDelStatus(1);
        return orderMapper.update(order,qw);
    }

    @Override
    public Integer cancelOrder(String no) {
        QueryWrapper<OrderMall> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(OrderMall.COL_ORDER_NO,no);
        List<OrderMall> orderMalls = orderMallMapper.selectList(queryWrapper);
        for (OrderMall orderMall : orderMalls) {
            if(orderMall.getOrderMallStatus() !=0){
                throw new ServiceException(ResultStatus.ORDER_CANCEL);
            }
        }
        QueryWrapper<Order> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq(Order.COL_ORDER_NO,no);
        Order order = new Order();
        order.setOrderStatus(0);
        orderMapper.update(order,queryWrapper2);
        return 1;
    }


}
